package org.hackystat.sdsa.service.resource.devstream;

import static org.junit.Assert.assertEquals;

import java.util.List;

import javax.xml.datatype.XMLGregorianCalendar;

import org.hackystat.sdsa.analyzer.model.activity.edit.EditActivity;
import org.hackystat.sdsa.analyzer.model.activity.edit.ProductionEditActivity;
import org.hackystat.sdsa.service.client.SdsaClient;
import org.hackystat.sdsa.service.resource.devstream.jaxb.DevStream;
import org.hackystat.sdsa.service.resource.devstream.jaxb.EpisodeTO;
import org.hackystat.sdsa.service.test.SdsaTestHelper;
import org.hackystat.sensorbase.client.SensorBaseClient;
import org.hackystat.sensorbase.resource.sensordata.jaxb.Properties;
import org.hackystat.sensorbase.resource.sensordata.jaxb.Property;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData;
import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDatas;
import org.hackystat.utilities.tstamp.Tstamp;
import org.junit.Test;

/**
 * Tests the SDSA's DevStream rest API 
 * 
 * @author Hongbing Kou
 */
public class TestDevStreamRestApi extends SdsaTestHelper {
  
  /** The user for this test case. */
  private String user = "TestTDD@hackystat.org";

  /**
   * Test that GET {host}/sdsa/{user}/Default/Day/2007-10-21/2007-10-23/testpass/TDD works properly.
   * 
   * First, it creates a test user and sends some sample DevEvent data to the SensorBase. 
   * Then, it invokes the GET request and checks to see that it obtains the right answer. 
   * Finally, it deletes the data and the user. 
   * @throws Exception If problems occur.
   */
  @Test public void getSampleDevStream() throws Exception {
    // [1] First, create a batch of DevEvent sensor data.
    SensorDatas batchData = new SensorDatas();
    batchData.getSensorData().add(makeDevEvent("2007-10-20T02:00:00", user));
    batchData.getSensorData().add(makeDevEvent("2007-10-21T02:10:00", user));
    batchData.getSensorData().add(makeDevEvent("2007-10-22T23:55:00", user));
    batchData.getSensorData().add(makeDevEvent("2007-10-23T00:01:00", user));
    
    // Connect to the sensorbase and register the user. 
    SensorBaseClient.registerUser(getSensorBaseHostName(), user);
    SensorBaseClient client = new SensorBaseClient(getSensorBaseHostName(), user, user);
    client.authenticate();
    // Send the sensor data to the SensorBase. 
    client.putSensorDataBatch(batchData);
    
    // Now connect to the Sdsa server. 
    SdsaClient sdsaClient = new SdsaClient(getSdsaHostName(), user, user);
    sdsaClient.authenticate(); 
    DevStream devStream =  sdsaClient.getDevStream(user, "Default", "testpass", "TDD", 
        Tstamp.makeTimestamp("2007-10-20"), Tstamp.makeTimestamp("2007-10-24"));
    List<EpisodeTO> episodes = devStream.getEpisodeTO();
    
    assertEquals("Check number of episodes", 1, episodes.size());
    EpisodeTO episode = episodes.get(0);
    assertEquals("Check number of activities", 1, episode.getActivityTO().size());
  }
  
  /**
   * Creates a sample SensorData DevEvent instance given a timestamp and a user. 
   * @param tstampString The timestamp as a string
   * @param user The user.
   * @return The new SensorData DevEvent instance.
   * @throws Exception If problems occur. 
   */
  private SensorData makeDevEvent(String tstampString, String user) throws Exception {
    XMLGregorianCalendar tstamp = Tstamp.makeTimestamp(tstampString);
    String sdt = "DevEvent";
    SensorData data = new SensorData();
    String tool = "Eclipse";
    data.setTool(tool);
    data.setOwner(user);
    data.setSensorDataType(sdt);
    data.setTimestamp(tstamp);
    data.setResource("file://C:/com/foo/Bar.java");
    data.setRuntime(tstamp);
    
    Properties props = new Properties();
    data.setProperties(props);
    
    Property type = new Property();
    type.setKey("Type");
    type.setValue("Edit");
    props.getProperty().add(type);
    
    Property subType = new Property();
    subType.setKey("Subtype");
    subType.setValue("StateChange");
    props.getProperty().add(subType);
    
    Property currentSize = new Property();
    currentSize.setKey(EditActivity.CURRENT_SIZE);
    currentSize.setValue("269");
    props.getProperty().add(currentSize);

    Property className = new Property();
    className.setKey(ProductionEditActivity.CLASS_NAME);
    className.setValue("com.foo.Bar");
    props.getProperty().add(className);

    Property currentStatements = new Property();
    currentStatements.setKey(ProductionEditActivity.CURRENT_STATEMENTS);
    currentStatements.setValue("210");
    props.getProperty().add(currentStatements);

    Property currentMethods = new Property();
    currentMethods.setKey(ProductionEditActivity.CURRENT_METHODS);
    currentMethods.setValue("2");
    props.getProperty().add(currentMethods);

    return data;
  }
}